using System.Collections.Generic;
using System.Web.Mvc;
using ETestIT.Core;
using MvcContrib.Pagination;
using SharpArch.Core;
using SharpArch.Core.PersistenceSupport;
using SharpArch.Web.NHibernate;

namespace ETestIT.Web.Controllers
{
    [HandleError]
    public class UsersController : Controller
    {
        private readonly IRepository<User> userRepository;

        public UsersController(IRepository<User> userRepository)
        {
            Check.Require(userRepository != null, "userRepository may not be null");

            this.userRepository = userRepository;
        }

        [Transaction]
        public ActionResult Index(int? page )
        {
            var users = userRepository.GetAll().AsPagination(page ?? 1,20 );
            return View(users);
        }

        [Transaction]
        public ActionResult Show(int id)
        {
            User user = userRepository.Get(id);
            return View(user);
        }

        public ActionResult Create()
        {
            UserFormViewModel viewModel = UserFormViewModel.CreateUserFormViewModel();
            return View(viewModel);
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(User user)
        {
            if (ViewData.ModelState.IsValid && user.IsValid())
            {
                userRepository.SaveOrUpdate(user);

                TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] =
                    "The user was successfully created.";
                return RedirectToAction("Index");
            }

            UserFormViewModel viewModel = UserFormViewModel.CreateUserFormViewModel();
            viewModel.User = user;
            return View(viewModel);
        }

        [Transaction]
        public ActionResult Edit(int id)
        {
            UserFormViewModel viewModel = UserFormViewModel.CreateUserFormViewModel();
            viewModel.User = userRepository.Get(id);
            return View(viewModel);
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(User user)
        {
            User userToUpdate = userRepository.Get(user.Id);
            TransferFormValuesTo(userToUpdate, user);

            if (ViewData.ModelState.IsValid && user.IsValid())
            {
                TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] =
                    "The user was successfully updated.";
                return RedirectToAction("Index");
            }
            else
            {
                userRepository.DbContext.RollbackTransaction();

                UserFormViewModel viewModel = UserFormViewModel.CreateUserFormViewModel();
                viewModel.User = user;
                return View(viewModel);
            }
        }

        private void TransferFormValuesTo(User userToUpdate, User userFromForm)
        {
            userToUpdate.Name = userFromForm.Name;
            userToUpdate.Password = userFromForm.Password;
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Delete(int id)
        {
            string resultMessage = "The user was successfully deleted.";
            User userToDelete = userRepository.Get(id);

            if (userToDelete != null)
            {
                if (IsNotCurrentLoggedIn(userToDelete))
                {
                    userRepository.Delete(userToDelete);

                    try
                    {
                        userRepository.DbContext.CommitChanges();
                    }
                    catch
                    {
                        resultMessage = "A problem was encountered preventing the user from being deleted. " +
                                        "Another item likely depends on this user.";
                        userRepository.DbContext.RollbackTransaction();
                    }
                }
                else
                {
                    resultMessage = "The user could not be deleted. It may already have been deleted or is current.";
                }

                TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = resultMessage;
            }
            return RedirectToAction("Index");
        }

        private bool IsNotCurrentLoggedIn(User userToDelete)
        {
            return !userToDelete.Name.Equals(User.Identity.Name);
        }

        #region Nested type: UserFormViewModel

        /// <summary>
        /// Holds data to be passed to the User form for creates and edits
        /// </summary>
        public class UserFormViewModel
        {
            private UserFormViewModel()
            {
            }

            public User User { get; internal set; }

            /// <summary>
            /// Creation method for creating the view model. Services may be passed to the creation 
            /// method to instantiate items such as lists for drop down boxes.
            /// </summary>
            public static UserFormViewModel CreateUserFormViewModel()
            {
                var viewModel = new UserFormViewModel();

                return viewModel;
            }
        }

        #endregion
    }
}